﻿using System;
using System.Data;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using POS.BusinessEntities;
using POS.DataObjects;

namespace POS.DataObjectsTest
{   
    [TestClass]
    public class DOContactoTest
    {
        #region Declarations
        private static Database db;
        private const string TestUser = "testUser";
        private const int EmpresaId = 1;

        #endregion

        #region Properties: Non-Public

        private static Database Db
        {
            get
            {
                if (db == null)
                    db = DatabaseFactory.CreateDatabase();
                return db;
            }
        }

        #endregion

        #region Test Methods

        [TestMethod]
        public void GetContactosList()
        {
            CreateContacto("TestName", "C", 1);
            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from contacto where empresaId = " + EmpresaId + " and tipo = 'C' and referencia = 1 and activo=1");
            var results = new DOContacto().GetList(EmpresaId, TipoContacto.Clientes, 1);
            Helper.AssertGetListResult(ds, results);
        }

        [TestMethod]
        public void SaveContactoNew()
        {
            const string name = "TestName";
            const TipoContacto tipo = TipoContacto.Clientes;
            const int referencia = 1;
            const string puesto = "puesto";
            const string email = "email";
            const string telefono = "telefono";
            const string celular = "celular";
            const string notas = "notas";
            
            var entity = new BEContacto
            {
                Nombre = name,
                Celular = celular,
                Email = email,
                Notas = notas,
                Puesto = puesto,
                Referencia = referencia,
                Telefono = telefono,
                Tipo = tipo
            };
            Db.ExecuteNonQuery(CommandType.Text, "delete contacto where empresaId = " + EmpresaId);
            new DOContacto().Save(entity, EmpresaId, TestUser);
            
            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from contacto where empresaId=" + EmpresaId + " and tipo='C' and activo = 1");
            Assert.IsNotNull(ds);
            Assert.AreEqual(1, ds.Tables.Count);
            Assert.AreEqual(1, ds.Tables[0].Rows.Count);
            var row = ds.Tables[0].Rows[0];
            Assert.IsTrue((int)row["ContactoId"] > 0);
            Assert.AreEqual(name, row["Nombre"]);
            Assert.AreEqual(tipo, StringToTipoContacto(row["tipo"].ToString()));
            Assert.AreEqual(referencia, row["referencia"]);
            Assert.AreEqual(puesto, row["puesto"]);
            Assert.AreEqual(email, row["email"]);
            Assert.AreEqual(telefono, row["telefono"]);
            Assert.AreEqual(celular, row["celular"]);
            Assert.AreEqual(notas, row["notas"]);
            Assert.AreEqual(true, row["Activo"]);
            Assert.AreEqual(TestUser, row["ModificadoPor"]);
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaModificacion"].ToString()).ToShortDateString());
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaCreacion"].ToString()).ToShortDateString());
        }

        [TestMethod]
        public void SaveEstacionExisting()
        {
            const string name = "TestName";
            const TipoContacto tipo = TipoContacto.Clientes;
            const int referencia = 1;
            const string puesto = "puesto";
            const string email = "email";
            const string telefono = "telefono";
            const string celular = "celular";
            const string notas = "notas";

            DeleteContacto(name);
            var id = CreateContacto(name, "C", referencia);
            var expectedName = name + DateTime.Now.Ticks;
            var expectedUser = TestUser + DateTime.Now.Ticks;
            var entity = new BEContacto
            {
                Id = id,
                Nombre = expectedName,
                Celular = celular,
                Email = email,
                Notas = notas,
                Puesto = puesto,
                Referencia = referencia,
                Telefono = telefono,
                Tipo = tipo
            };

            new DOContacto().Save(entity, EmpresaId, expectedUser);

            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from contacto where empresaId=" + EmpresaId + " and tipo='C' and activo = 1");
            Assert.IsNotNull(ds);
            Assert.AreEqual(1, ds.Tables.Count);
            Assert.AreEqual(1, ds.Tables[0].Rows.Count);
            var row = ds.Tables[0].Rows[0];
            Assert.IsTrue((int)row["ContactoId"] > 0);
            Assert.AreEqual(expectedName, row["Nombre"]);
            Assert.AreEqual(tipo, StringToTipoContacto(row["tipo"].ToString()));
            Assert.AreEqual(referencia, row["referencia"]);
            Assert.AreEqual(puesto, row["puesto"]);
            Assert.AreEqual(email, row["email"]);
            Assert.AreEqual(telefono, row["telefono"]);
            Assert.AreEqual(celular, row["celular"]);
            Assert.AreEqual(notas, row["notas"]);
            Assert.AreEqual(true, row["Activo"]);
            Assert.AreEqual(expectedUser, row["ModificadoPor"]);
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaModificacion"].ToString()).ToShortDateString());
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaCreacion"].ToString()).ToShortDateString());
        }
        
        #endregion

        #region Test Utilities

        private static void DeleteContacto(string name)
        {
            Db.ExecuteNonQuery(CommandType.Text, "delete contacto where empresaId = " + EmpresaId + " and nombre='" + name + "'");
        }

        private static int CreateContacto(string name, string type, int referencia)
        {
            const int id = 999;
            Db.ExecuteNonQuery(CommandType.Text, "Delete Contacto where ContactoId = " + id);
            var sql = "Insert into Contacto " +
                      " (ContactoId, EmpresaId, Tipo, Activo, Nombre, Referencia, Puesto, Email, " +
                      "  Telefono, Celular, Notas, FechaCreacion, FechaModificacion, ModificadoPor) " +
                      "Values (" + id + ", " + EmpresaId + ",'" + type + "'," + referencia + ", '" + name + "', 1, 'Gerente', 'email', " + 
                               "'telef', 'cel', 'notas', getdate(), getdate(), 'TestUser')";
            Db.ExecuteNonQuery(CommandType.Text, sql);
            return id;
        }

        private static TipoContacto StringToTipoContacto(string tipo)
        {
            switch (tipo)
            {
                case "C":
                    return TipoContacto.Clientes;
                case "P":
                    return TipoContacto.Proveedores;
            }
            return TipoContacto.Clientes; //default
        }

        #endregion
    }
}
